// Copyright (c) 2016, Open DICOMweb Project. All rights reserved.
// Use of this source code is governed by the open source license
// that can be found in the LICENSE file.
// Author: Jim Philbin <jfphilbin@gmail.edu> -
// See the AUTHORS file for other contributors.

import 'uid.dart';
import 'uid_errors.dart';

/// A singleton class used to ensure that all [Uid]s are unique.
abstract class SupportedUid {
  /// [Uid]s that are known to the src.
  dynamic get knownUids;

  /// Returns _true_ if [uid] is in knownUids.
  bool contains(Uid uid);

  /// Checks that the [uid] is not present in [knownUids].
  /// Thrown a [InvalidUidError] if it is present.
  Uid checkNotPresent(Uid uid) =>
      (contains(uid)) ? uid : invalidDuplicateUid(uid);

  /// Returns a [SupportedUidList] or [SupportedUidMap].
  static SupportedUid? initialize([String? type, int initialLength = 500]) {
    if (type == 'list') return  SupportedUidList(initialLength);
    if (type == 'map') return  SupportedUidMap();
    return null;
  }
}

/// A singleton class used to ensure that all [Uid]s are unique.
class SupportedUidList extends SupportedUid {
  /// A [List] of known [Uid]s.
  @override
  final List<Uid> knownUids;

  SupportedUidList([int initialLength = 500]) : knownUids = [];

  @override
  bool contains(Uid uid) => knownUids.contains(uid);

  void add(Uid uid, [Object? _]) {
    checkNotPresent(uid);
    knownUids.add(uid);
  }
}

/// A singleton class used to ensure that all [Uid]s are unique.
/// The primary use is by Entities.
class SupportedUidMap extends SupportedUid {
  /// A [Map] of [Uid]s to [Object] of all [Uid]s created.
  /// It can also be used to lookup an [Object] by its [Uid].
  @override
  final Map<Uid, dynamic> knownUids = {};

  SupportedUidMap();

  @override
  bool contains(Uid uid) => knownUids.containsKey(uid);

  void add(Uid uid, o) {
    checkNotPresent(uid);
    knownUids.putIfAbsent(uid, o);
  }
}
